package net.aiion.weave.impl.bytecode;

// TODO respect the stuff in the "Test" project
public class BytecodeLoader extends ClassLoader
{
    private String[] ignoredPackages = {
        "java.", "javax.", "sun."
    };

    private final BytecodeStoreImpl bytecodeStore;

    public BytecodeLoader(final BytecodeStoreImpl aBytecodeStore) {
        this(aBytecodeStore, ClassLoader.getSystemClassLoader());
    }

    public BytecodeLoader(final BytecodeStoreImpl aBytecodeStore, final ClassLoader aParentClassLoader) {
        super(aParentClassLoader);
        bytecodeStore = aBytecodeStore;
    }

    @Override
    protected Class<?> loadClass(final String aClassName, final boolean aResolve) throws ClassNotFoundException {
        Class<?> loadedClass = findLoadedClass(aClassName);
        if (loadedClass == null) {
            for (String ignoredPackage : ignoredPackages) {
                if (aClassName.startsWith(ignoredPackage)) {
                    loadedClass = super.loadClass(aClassName, aResolve);
                }
            }
        }

        if (loadedClass == null) {
            loadedClass = loadClass1(aClassName);
        }

        if (loadedClass == null) {
            loadedClass = Class.forName(aClassName);
        }

        if (aResolve) {
            resolveClass(loadedClass);
        }

        return loadedClass;
    }

    private Class<?> loadClass1(final String aClassName) throws ClassNotFoundException {
        final byte[] classBytes = bytecodeStore.removeClass(aClassName);
        if (classBytes == null) {
            return null;
        }

        return defineClass(aClassName, classBytes, 0, classBytes.length);
    }
}
